package com.zbs.framework.dao.user.service.impl;

import com.zbs.framework.common.constant.Constants;
import com.zbs.framework.common.utils.CommonUtil;
import com.zbs.framework.common.utils.Constant;
import com.zbs.framework.common.utils.ErrEnum;
import com.zbs.framework.common.utils.ErrorAssert;
import com.zbs.framework.dao.event.UserCreatedEvent;
import com.zbs.framework.dao.passport.base.repository.MNAccountRepository;
import com.zbs.framework.dao.passport.entity.MNNormal;
import com.zbs.framework.dao.passport.normal.repository.MNNormalRepository;
import com.zbs.framework.dao.passport.normal.service.NormalAccountService;
import com.zbs.framework.dao.phonevcode.service.PhoneVCodeService;
import com.zbs.framework.dao.user.UserConst;
import com.zbs.framework.dao.user.entity.BaseUserInfo;
import com.zbs.framework.dao.user.entity.MNBaseUser;
import com.zbs.framework.dao.user.entity.UserRole;
import com.zbs.framework.dao.user.repository.BaseUserRepository;
import com.zbs.framework.dao.user.repository.UserRoleRepository;
import com.zbs.framework.dao.user.service.BaseUserService;
import com.zbs.framework.dao.user.service.DefaultRoleService;
import com.zbs.framework.dao.utils.SecurityUserUtils;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Zbs
 * 2018-11-23 17:24
 */
@Service
@Transactional
public class BaseUserServiceImpl implements BaseUserService {

    @Autowired
    private MNNormalRepository normalRepository;
    @Autowired
    private BaseUserRepository baseUserRepository;
    @Autowired
    private NormalAccountService normalAccountService;
    @Autowired
    private MNAccountRepository accountRepository;
    @Autowired
    private PhoneVCodeService phoneVCodeService;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private DefaultRoleService defaultRoleService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private MNNormalRepository mnNormalRepository;
    @Autowired
    private SecurityUserUtils securityUserUtils;

    @Override
    public Map<String, Object> usernameLogin(String username, String pwd, String entryType) {
        ErrorAssert.trimHasLength(username, "账号不能为空");
        ErrorAssert.trimHasLength(pwd, "密码不能为空");
        //查询用户
        final MNNormal accNormal = this.mnNormalRepository.findByUsernameAndDeleted(username, Constant.YES);
        //判断用户是否注册
        ErrorAssert.notNull(accNormal, ErrEnum.USER_NOT_EXIST.getErrMsg());
        //用户基本信息,角色id
        final var baseUser = this.baseUserRepository.findByAcctUuid(accNormal.getAcctUuid());
        return this.securityUserUtils.returnSecurityUser(baseUser,pwd, accNormal, entryType,null);
    }

    @Override
    public Map<String, Object> phoneLogin(String phone, String code, String entryType) {
        //手机号验证码校验
        this.phoneVCodeService.validatePhoneVCode(phone, code, Constants.LOGIN_CODE_TYPE);
        //查询用户
        final MNNormal accNormal = this.mnNormalRepository.findByUsernameAndDeleted(phone,Constant.YES);
        //判断用户是否注册
        ErrorAssert.notNull(accNormal, ErrEnum.USER_NOT_EXIST.getErrMsg());
        //查询用户基本信息
        final var baseUser = this.baseUserRepository.findByAcctUuid(accNormal.getAcctUuid());
        //账号不存在
        ErrorAssert.notNull(baseUser, ErrEnum.USER_NOT_EXIST.getErrMsg());
        return this.securityUserUtils.returnSecurityUser(baseUser, accNormal, entryType,null);
    }

    @Override
    public MNBaseUser createUser(String acctUuid, Integer[] roleIds, String name,
                                 Character gender, String birthday,
                                 String headImg, String phone) {
        // 参数检查
        ErrorAssert.notNull(acctUuid, "Account uuid can not be null!");
        ErrorAssert.hasLength(name, "Name can not be empty!");
        ErrorAssert.isTrue(gender.equals(UserConst.MALE) || gender.equals(UserConst.FEMALE),
                "Illegal value of gender!");
        // 创建用户
        MNBaseUser user = new MNBaseUser(acctUuid, name, gender,
                new Date(), UserConst.USER_TYPE_NORMAL, birthday,
                headImg, phone);
        baseUserRepository.save(user);
        // 创建用户角色关联关系
        saveUserRoles(user.getId(), roleIds);

        //创建用户推送消息
        this.applicationContext.publishEvent(new UserCreatedEvent(this,acctUuid, user.getId(), user.getName()));

        return user;
    }

    @Override
    public void saveUserRoles(Long userId, Integer[] roleIds) {
        // 删除原有关系
        userRoleRepository.deleteAllByUserId(userId);
        // 添加新关系
        if (roleIds == null) return;
        if (roleIds.length == 0) return;
        for (Integer roleId : roleIds) {
            userRoleRepository.save(new UserRole(userId, roleId));
        }
    }

    @Override
    public void changePwd(Long userId, String oldPwd, String newPwd) {
        MNBaseUser baseUser = baseUserRepository.findById(userId).orElse(null);
        ErrorAssert.notNull(baseUser, ErrEnum.USER_NOT_EXIST);

        normalAccountService.changePwd(baseUser.getAcctUuid(), oldPwd, newPwd);
    }


    @Override
    public MNBaseUser registerNormal(String username, String pwd) {
        // 创建用户
        String name = "uid_" + UUID.randomUUID().toString().replaceAll("-", "");
        return registerNormal(name,username,pwd);
    }

    @Override
    public MNBaseUser registerNormal(String name, String username, String pwd) {
        // 创建账号
        MNNormal normal = normalAccountService.create(username, pwd);
        // 创建用户
        Integer defaultRoleId = this.defaultRoleService.getDefaultRoleId();
        Integer[] roleIds = defaultRoleId== null ? null :  new Integer[] {defaultRoleId};
        return createUser(normal.getAcctUuid(), roleIds, name, UserConst.MALE,
                null, "", "");
    }

    @Override
    public MNBaseUser registerNormal(String name, String username, String pwd, Character userType) {
        MNBaseUser user = this.registerNormal(name, username, pwd);
        user.setUserType(userType);
        this.baseUserRepository.save(user);
        return user;
    }

    @Override
    public MNBaseUser changeUserInfo(Long userId, String name, String headImg, Character gender, String birthday) {
        MNBaseUser baseUser = this.baseUserRepository.findById(userId).orElse(null);
        if (baseUser != null) {
            if (StringUtils.hasLength(name)) {
                baseUser.setName(name);
            }
            if (StringUtils.hasLength(headImg)) {
                baseUser.setHeadImg(headImg);
            }
            if (gender != null) {
                baseUser.setGender(gender);
            }
            if (StringUtils.hasLength(birthday)) {
                baseUser.setBirthday(name);
            }
            this.baseUserRepository.save(baseUser);
            return baseUser;
        }
        return null;
    }

    @Override
    public void registerPhone(String phone, String pwd, String vCode) {
        // 检查手机号格式
        ErrorAssert.isTrue(CommonUtil.matchPhone(phone), ErrEnum.PHONE_FORMAT_ERR);
        // 短信验证码校验
        phoneVCodeService.validatePhoneVCode(false,phone, vCode, Constants.REGISTER_CODE_TYPE);
        // 注册账号
        MNBaseUser baseUser = registerNormal(phone, pwd);
        // 设置用户手机号
        baseUser.setPhone(phone);
        baseUserRepository.save(baseUser);
    }

    @Override
    public BaseUserInfo getMyUserInfo(Long userId) {
        MNBaseUser mnBaseUser = this.baseUserRepository.findById(userId).orElse(null);
        if (mnBaseUser != null) {
            return new BaseUserInfo(mnBaseUser,null);
        }
        return null;
    }
}
